package com.tsy.server.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tsy.server.manage.dao.IDeviceMapper;
import com.tsy.server.manage.model.dto.DeviceDTO;
import com.tsy.server.manage.model.entity.DeviceEntity;
import com.tsy.server.system.entity.Project;
import com.tsy.server.system.entity.ProjectUser;
import com.tsy.server.system.entity.User;
import com.tsy.server.system.entity.dto.ProjectDTO;
import com.tsy.server.system.entity.dto.ProjectUserDTO;
import com.tsy.server.system.entity.vo.ProjectQueryVO;
import com.tsy.server.system.entity.vo.ProjectVO;
import com.tsy.server.system.mapper.ProjectMapper;
import com.tsy.server.system.mapper.ProjectUserMapper;
import com.tsy.server.system.mapper.UserMapper;
import com.tsy.server.component.security.SecurityUtils;
import com.tsy.server.system.service.ProjectService;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 项目管理服务实现类
 */
@Service
public class ProjectServiceImpl implements ProjectService {

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private ProjectUserMapper projectUserMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IDeviceMapper deviceMapper;

    @Override
    public List<Project> listProjects(ProjectQueryVO projectQueryVO) {
        LambdaQueryWrapper<Project> queryWrapper = Wrappers.lambdaQuery(Project.class);
        Long orgId = SecurityUtils.getCurrentOrgId();
        queryWrapper.eq(Project::getOrgId, orgId);
        queryWrapper.like(projectQueryVO.getName() != null, Project::getName, projectQueryVO.getName());
        queryWrapper.eq(projectQueryVO.getJoinAble() != null, Project::getJoinAble, projectQueryVO.getJoinAble());
        queryWrapper.eq(projectQueryVO.getStatus() != null, Project::getStatus, projectQueryVO.getStatus());
        queryWrapper.like(projectQueryVO.getJoinCode() != null, Project::getJoinCode, projectQueryVO.getJoinCode());
        if (projectQueryVO.getCreateTimeSort() != null && projectQueryVO.getCreateTimeSort() == 0) {
            queryWrapper.orderByAsc(Project::getCreateTime);
        } else {
            queryWrapper.orderByDesc(Project::getCreateTime);
        }

        // 是否已加入查询
        Long currentUserId = SecurityUtils.getCurrentUserId();

//        if (projectQueryVO.getJoined() == 0) { // 未加入
//            // 不是创建并且不是组织下该项目中的成员
//            queryWrapper.ne(Project::getCreatorId, currentUserId);
//            List<ProjectUser> projectUserList = projectUserMapper.selectList(
//                    Wrappers.lambdaQuery(ProjectUser.class)
//                            .eq(ProjectUser::getUserId, currentUserId)
//                            .eq(ProjectUser::getOrgId, orgId));
//            List<Long> projectIdList = projectUserList.stream().map(ProjectUser::getProjectId).collect(Collectors.toList());
//            queryWrapper.notIn(Project::getId, projectIdList);
//            return projectMapper.selectList(queryWrapper);
//        }else {
//            if (projectQueryVO.getJoined() == 2) { // 已创建
//                queryWrapper.eq(Project::getCreatorId, currentUserId);
//            } else { // 已加入
//                List<ProjectUser> projectUserList = projectUserMapper.selectList(
//                        Wrappers.lambdaQuery(ProjectUser.class)
//                                .eq(ProjectUser::getUserId, currentUserId)
//                                .eq(ProjectUser::getOrgId, orgId));
//                List<Long> projectIdList = projectUserList.stream().map(ProjectUser::getProjectId).collect(Collectors.toList());
//                queryWrapper.in(Project::getId, projectIdList);
//            }
//            return projectMapper.selectList(queryWrapper);
//        }

        // 如果不是超级管理员，则查询已加入
        if (!("admin").equals(SecurityUtils.getCurrentOrgRoleKey())) {
            List<ProjectUser> projectUserList = projectUserMapper.selectList(
                        Wrappers.lambdaQuery(ProjectUser.class)
                                .eq(ProjectUser::getUserId, currentUserId)
                                .eq(ProjectUser::getOrgId, orgId));
            List<Long> projectIdList = projectUserList.stream().map(ProjectUser::getProjectId).collect(Collectors.toList());
            if (!projectIdList.isEmpty()) {
                queryWrapper.in(Project::getId, projectIdList);
            }
        }

        return projectMapper.selectList(queryWrapper).stream().peek(project -> {
            User user = userMapper.selectById(project.getCreatorId());
            project.setUsername(user.getUsername());
        }).collect(Collectors.toList());
    }


    @Override
    @Transactional
    public void createProject(ProjectDTO projectDTO) {
        Project project = new Project();
        BeanUtils.copyProperties(projectDTO, project);
        // 设置组织ID
        Long orgId = SecurityUtils.getCurrentOrgId();
        project.setOrgId(orgId);
        // 项目状态
        project.setStatus(0);
        Long userId = SecurityUtils.getCurrentUserId();
        // 项目创建者
        project.setCreatorId(userId);

        if (projectDTO.getJoinAble() == 1) {
            String joinCode = RandomStringUtils.random(6, false, true);
            project.setJoinCode(joinCode);
            if (project.getDeadline() == null) {
                LocalDateTime now = LocalDateTime.now().plusDays(7);
                project.setDeadline(now);
            }
        } else {
            project.setJoinAble(0);
        }
        projectMapper.insert(project);

        // 关联人员
        for (ProjectUserDTO dto : projectDTO.getProjectUsers()) {
            ProjectUser projectUser = new ProjectUser();
            projectUser.setProjectId(project.getId());
            projectUser.setUserId(dto.getUserId());
            projectUser.setOrgId(orgId);
            projectUser.setUserProjectName(dto.getUserProjectName());
            projectUserMapper.insert(projectUser);
        }

        // 关联设备  无人机机场一同关联
        for (DeviceDTO dto : projectDTO.getProjectDevices()) {
            DeviceEntity deviceEntity = new DeviceEntity();
            deviceEntity.setProjectId(project.getId());
            LambdaUpdateWrapper<DeviceEntity> updateWrapper = Wrappers.lambdaUpdate(DeviceEntity.class).eq(DeviceEntity::getDeviceSn, dto.getDeviceSn());
            deviceMapper.update(deviceEntity, updateWrapper);

            // 查询无人机是否关联机场
            DeviceEntity dock = deviceMapper.selectOne(Wrappers.lambdaQuery(DeviceEntity.class).eq(DeviceEntity::getChildSn, dto.getDeviceSn()));
            if (dock != null) {
                dock.setProjectId(project.getId());
                deviceMapper.updateById( dock);
            }
        }
    }

    @Override
    @Transactional
    public void updateProject(ProjectDTO projectDTO) {
        if (projectDTO.getId() == null) {
            throw new RuntimeException("项目ID不能为空");
        }

        Project project = projectMapper.selectById(projectDTO.getId());
        
        if (project == null) {
            throw new RuntimeException("项目不存在");
        }

        // 如果开启申请码，则生成加入码
        if (project.getJoinAble() == 0  && projectDTO.getJoinAble() == 1) {
            String joinCode = RandomStringUtils.random(6, false, true);
            project.setJoinCode(joinCode);
            if (project.getDeadline() == null) {
                LocalDateTime now = LocalDateTime.now().plusDays(7);
                project.setDeadline(now);
            }
        }

        // 更新项目信息
        BeanUtils.copyProperties(projectDTO, project);

        projectMapper.updateById(project);

        // 删除旧的关联
        projectUserMapper.delete(Wrappers.lambdaQuery(ProjectUser.class).eq(ProjectUser::getProjectId, project.getId()));
        // 更新人员关联关系
        for (ProjectUserDTO dto : projectDTO.getProjectUsers()) {
            ProjectUser projectUser = new ProjectUser();
            projectUser.setProjectId(project.getId());
            projectUser.setUserId(dto.getUserId());
            projectUser.setOrgId(SecurityUtils.getCurrentOrgId());
            projectUser.setUserProjectName(dto.getUserProjectName());
            projectUserMapper.insert(projectUser);
        }

        // 删除之前的设备关联
        DeviceEntity updateEntity = new DeviceEntity();
        updateEntity.setProjectId(0L);
        deviceMapper.update(updateEntity, Wrappers.lambdaUpdate(DeviceEntity.class).eq(DeviceEntity::getProjectId, project.getId()));

        // 关联设备  无人机机场一同关联
        for (DeviceDTO dto : projectDTO.getProjectDevices()) {
            DeviceEntity deviceEntity = new DeviceEntity();
            deviceEntity.setProjectId(project.getId());
            deviceMapper.update(deviceEntity, Wrappers.lambdaUpdate(DeviceEntity.class).eq(DeviceEntity::getDeviceSn, dto.getDeviceSn()));

            // 查询无人机是否关联机场
            DeviceEntity dock = deviceMapper.selectOne(Wrappers.lambdaQuery(DeviceEntity.class).eq(DeviceEntity::getChildSn, dto.getDeviceSn()));
            if (dock != null) {
                dock.setProjectId(project.getId());
                deviceMapper.updateById( dock);
            }
        }
    }

    @Override
    @Transactional
    public void deleteProject(Long id) {
        if (id == null) {
            throw new RuntimeException("项目ID不能为空");
        }

        int count = projectMapper.deleteById(id);
        if (count == 0) {
            throw new RuntimeException("项目不存在");
        }
        // 删除项目关联人员
        projectUserMapper.delete(Wrappers.lambdaQuery(ProjectUser.class).eq(ProjectUser::getProjectId, id));
    }

    @Override
    public ProjectVO getProjectDetail(Long id) {
        Project project = projectMapper.selectById(id);

        if (project == null) {
            throw new RuntimeException("项目不存在");
        }

        ProjectVO projectVO = new ProjectVO();
        BeanUtils.copyProperties(project, projectVO);
        // 获取项目关联人员
        Long orgId = SecurityUtils.getCurrentOrgId();
        List<ProjectUser> projectUserList = projectUserMapper.selectList(
                Wrappers.lambdaQuery(ProjectUser.class)
                        .eq(ProjectUser::getProjectId, id)
                        .eq(ProjectUser::getOrgId, orgId));

        // 添加用户名字段
        projectUserList = projectUserList.stream().peek(projectUser -> {
            User user = userMapper.selectById(projectUser.getUserId());
            projectUser.setUsername(user.getUsername());
        }).collect(Collectors.toList());;
        projectVO.setProjectUsers(projectUserList);

        // 获取项目关联设备
        String workspaceId = SecurityUtils.getWorkspaceId();
        List<DeviceEntity> deviceList = deviceMapper.selectList(
                Wrappers.lambdaQuery(DeviceEntity.class)
                        .eq(DeviceEntity::getProjectId, id)
                        .eq(DeviceEntity::getWorkspaceId, workspaceId)
                        .eq(DeviceEntity::getBoundStatus, true)
                        .eq(DeviceEntity::getDomain, 0));

        projectVO.setProjectDevices(deviceList);

        return projectVO;
    }


    @Override
    @Transactional
    public void joinProjectByCode(String joinCode) {
        // TODO: 实现通过加入码加入项目的逻辑
        throw new RuntimeException("功能暂未实现");
    }

    @Override
    public void archiveProject(Long id) {
        Project project = projectMapper.selectById(id);
        if (project == null) {
            throw new RuntimeException("项目不存在");
        }
        project.setStatus(1);
        projectMapper.updateById(project);
    }
}